﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data;

namespace Hypermarket_Serial_Port
{
    class AddTransactionManager : CashierRegisterTaskManager
    {
        private Dictionary<string, string> mTransactionIDList = new Dictionary<string, string>();


        #region Constructor
        public AddTransactionManager()
        {
            DataTable Transaction = mDBManager.getTable(Constant.TRANSACTION_TABLE);
            foreach (DataRow dr in Transaction.Rows)
            {
                string id = dr[Constant.TRANSACTION_ID].ToString();
                mTransactionIDList.Add(id, id);
            }
        }
        #endregion


        #region Operation for adding transactions
        public override List<string> TaskOperation(List<string> receivedInfoList, Dictionary<string, CashierRegister> cashierDict)
        {
            try
            {
                SerialPortLog.Log("Add Transaction Start");
                string machineID = receivedInfoList[Constant.ZERO];
                string type = receivedInfoList[Constant.ONE];
                string productID = receivedInfoList[Constant.TWO];
                string quantity = receivedInfoList[Constant.THREE];
                SerialPortLog.LogOperation("Add Transaction: " + machineID);
                SerialPortLog.LogOperation("Barcode: " + productID);
                // check machier ID valid
                CashierRegister cashierRegister;
                if (cashierDict.TryGetValue(machineID, out cashierRegister))
                {
                    if (!cashierRegister.isTransactionStarted())
                    {
                        string transactionID = GenerateNextTransactionID();
                        cashierRegister.StartTransaction(transactionID);
                    }
                    return AddTransactionInfo(productID, quantity, cashierRegister, machineID, type);
                }
                else
                {
                    List<string> tempStr = new List<string>();
                    tempStr.Add(machineID);
                    tempStr.Add(type);
                    tempStr.Add(Constant.FAIL);
                    return tempStr;
                    SerialPortLog.LogOperation("Add Transaction Fail");
                    SerialPortLog.Log("Add Transaction Fail");
                    //tempStr.Add(Constant.LOGIN_FIRST_MSG);
                }
            }
            catch
            {
                SerialPortLog.LogOperation("Add Transaction Error");
                SerialPortLog.Log("Add Transaction Error");
                throw;
            }
        }
        #endregion


        #region Add Transaction
        private List<string> AddTransactionInfo(string productID, string quantity, CashierRegister cashierRegister, string machineID, string type)
        {
            // TO CHECK 
            Int32 unitSold = Int32.Parse(quantity);
            unitSold = cashierRegister.getPreviousQuantity(productID) + unitSold;
            if (unitSold <= Constant.MIN_QUALITY)
            {
                List<string> tempStr = new List<string>();
                tempStr.Add(machineID);
                tempStr.Add(type);
                tempStr.Add(Constant.FAIL);
                return tempStr;
                SerialPortLog.LogOperation("Add Transaction Fail");
                SerialPortLog.Log("Add Transaction Fail");
                //tempStr.Add(Constant.MSG_QUANTITY_ERROR);
            }

            DataRow[] rows = GetNoDiscountProductDataRows(productID);
            if (rows.Count() == Constant.ZERO)
            {
                List<string> tempStr = new List<string>();
                tempStr.Add(machineID);
                tempStr.Add(type);
                tempStr.Add(Constant.FAIL);
                SerialPortLog.LogOperation("Add Transaction Fail");
                SerialPortLog.Log("Add Transaction Fail");
                return tempStr;
            }

            if (Convert.ToInt32(rows.First()[Constant.QUANTITY]) < unitSold)
            {
                List<string> tempStr = new List<string>();
                tempStr.Add(machineID);
                tempStr.Add(type);
                tempStr.Add(Constant.FAIL);
                SerialPortLog.LogOperation("Add Transaction Fail");
                SerialPortLog.Log("Add Transaction Fail");
                return tempStr;
                //tempStr.Add(Constant.MSG_NOTENOUGH_QUANTITY);
            }
            else
            {
                return AddWithoutDiscTransaction(productID, quantity, cashierRegister, machineID, rows.First(), type);
            }
        }
        #endregion


        private DataRow[] GetNoDiscountProductDataRows(string productID)
        {
            DataTable Stock = mDBManager.getTable(Constant.STOCK_PRODUCT_TABLE);
            string query = Constant.PRODUCT_ID + Constant.EQUAL + Constant.SINGAL_QUOTE + productID +
                    Constant.SINGAL_QUOTE + Constant.AND + Constant.EXPIRE_DATE + Constant.MORE_THAN +
                    Constant.SINGAL_QUOTE + DateTime.Today + Constant.SINGAL_QUOTE;
            DataRow[] rows = Stock.Select(query);
            return rows;
        }

        private static List<string> AddWithoutDiscTransaction(string productID, string quantity, CashierRegister cashierRegister, string machineID, DataRow dr, string type)
        {            
            string name = dr[Constant.NAME].ToString();
            string sellingPrice = dr[Constant.SELLING_PRICE].ToString();
            string batchID = dr[Constant.BATCH_ID].ToString();
            string importPrice = dr[Constant.IMPORT_PRICE].ToString();

            cashierRegister.AddTransaction(productID, name, batchID, importPrice, sellingPrice, Constant.ZERO_PERCENTAGE, Convert.ToInt32(quantity)); //for database report purpose
            //string output = Constant.MSG_SCANNED + Constant.COLON + Constant.NEWLINE + Constant.PRODUCT_ID + Constant.COLON + Constant.SPACE + productID + Constant.NEWLINE + 
            //                Constant.NAME + Constant.COLON + Constant.SPACE + name + Constant.NEWLINE + Constant.SELLING_PRICE + Constant.COLON + Constant.SPACE + 
            //                Math.Round(Convert.ToDecimal(sellingPrice), Constant.TWO) + Constant.NEWLINE + Constant.QUANTITY + Constant.COLON + Constant.SPACE + quantity + Constant.NEWLINE  /***sound index****/;
            List<string> output = new List<string>();
            output.Add(machineID);
            output.Add(type);
            output.Add(Constant.SUCCESS);
            output.Add(name);
            output.Add(sellingPrice.ToString());
            /***add sound index;***/
            SerialPortLog.LogOperation("Add Transaction Successfully");
            SerialPortLog.Log("Add Transaction Successfully");
            return output;
        }

        #region Generate next Transaction ID
        private string GenerateNextTransactionID()
        {
            int id = int.Parse(mTransactionIDList.Last().Value) + Constant.ONE;
            mTransactionIDList.Add(id.ToString(), id.ToString());
            return id.ToString();
        }
        #endregion
    }
}